#include "forest.h"

Forest forest_Merge(Forest A, Forest B);
Forest forest_Append(Forest f, TreeNode *root);
int forest_Print(Forest f);

/*!
  Create an empty forest.
  /return The new forest
*/
Forest new_Forest()
{
	Forest f;
	f.Head = 0x0;
	f.Tail = 0x0;
	f.Print = forest_Print;
	f.Merge = forest_Merge;
	f.Append = forest_Append;
	return f;
}

/*!
  Formatted printing for a forest.
  Prints to stdout
  /param f The forest to print
  /return A global error code
*/
int forest_Print(Forest f)
{
	TreeNode *iter=f.Head;
	while (iter != 0x0)
	{
		iter->Print(iter, 0);
		iter = iter->NextSibling;
	}
	return EC_SUCCESS;
}

/*!
  Merge two forests at the root.
  Note: Merging only sets pointers, it does not create a new copy. The old forests will be defective.
  /param A First forest. Makes up the beginning of the new forest. This forest will be invalid.
  /param B Second forest. Makes up the end of the new forest. This forest will be invalid.
  /return The merged forest.
*/
Forest forest_Merge(Forest A, Forest B)
{
	Forest f = new(Forest);
	if (A.Head == 0x0)
	{
		f.Head = B.Head;
		f.Tail = B.Tail;
		return f;
	}
	if (B.Head == 0x0)
	{
		f.Head = A.Head;
		f.Tail = A.Tail;
		return f;
	}
	f.Head = A.Head;
	f.Tail = B.Tail;
	A.Tail->NextSibling = B.Head;
	B.Head->PreviousSibling = A.Tail;

	A.Head = 0x0;
	A.Tail = 0x0;
	B.Head = 0x0;
	B.Tail = 0x0;
	return f;
}
/*!
  Append a new tree onto the forest list
  /param f The forest to modify
  /param root The root of the new tree
  /return The resultant forest
*/
Forest forest_Append(Forest f, TreeNode *root)
{
	root->PreviousSibling=f.Tail;
	if (f.Head == 0x0)
		f.Head = root;
	else
		f.Tail->NextSibling = root;
	f.Tail = root;
	return f;
}
